/*
 * 
 */
package lik.http.videoplay.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lik.http.videoplay.service.MediaFileService;

import org.apache.log4j.Logger;

/**
 * 
 * 
 * @author <A HREF="mailto:li_kan@vobile.cn">Licey</A> 2012-2-21
 * 
 */
public class VideoPlayServlet extends HttpServlet {
	private static final Logger logger = Logger.getLogger(VideoPlayServlet.class);

	private static final long serialVersionUID = -6507550263346891307L;

	private MediaFileService mediaFileService;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String fileId = req.getParameter("fileId");

		if (fileId == null) {
			fileId = "0";
		}
		String rang = req.getHeader("Range");
		File file = mediaFileService.getMedias().get(Integer.parseInt(fileId));
		long start = 0, end = 0;
		if (rang != null) {
			rang = rang.substring("bytes=".length());
			String[] splt = rang.trim().split("-");
			start = Integer.parseInt(splt[0]);
			if (splt.length == 2) {
				end = Integer.parseInt(splt[1]);
			}
		}
		if (end == 0) {
			end = file.length();
		}

		resp.setContentType("video/mp4");
		resp.setHeader("Accept-Ranges", "bytes");
		resp.setHeader("Content-Length", Long.toString(end - start));
		resp.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + file.length());
		resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//206

		OutputStream out = resp.getOutputStream();
		printFile(out, file, start, end);
	}

	private void printFile(OutputStream out, File file, long start, long end) throws IOException {
		RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
		if (start != 0) {
			skip(randomAccessFile, (int) start);
		}
		try {
			int temp = 0;
			byte[] data = new byte[1024];
			long total = end - start + 1;
			while (((temp = randomAccessFile.read(data)) != -1) && (total > 0)) {
				out.write(data, 0, (int) minLong(total, temp));
				out.flush();
				total = total - temp;
			}
		} finally {
			randomAccessFile.close();
		}
	}

	private void skip(RandomAccessFile randomAccessFile, int skip) throws IOException {
		int temp = randomAccessFile.skipBytes(skip);
		if (skip - temp != 0) {
			skip(randomAccessFile, skip - temp);
		}
	}

	private long minLong(long a, long b) {
		return a > b ? b : a;
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		mediaFileService = MediaFileService.getMediaFileService();
		super.init(config);
	}
}
